package sort;

/**
 * 归并排序
 * 稳定：归并合并左右数组的时候，相等先取左边的数，就可以保证稳定性，
 * 因为右边的数本来就在右边，所以后取
 *
 * @author Liaorun
 */
public class MergeSort {

    public static void main(String[] args) {

    }

    public static void mergeSort(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }

        process(arr, 0, arr.length - 1);
    }

    private static void process(int[] arr, int l, int r) {
        if (l == r) {
            return;
        }

        int mid = l + ((r - l) >> 1);

        process(arr, l, mid);
        process(arr, mid + 1, r);
        merge(arr, l, mid, r);
    }

    private static void merge(int[] arr, int l, int mid, int r) {
        int[] help = new int[r - l + 1];
        int i = 0;
        int p1 = l;
        int p2 = mid + 1;

        while (p1 <= mid && p2 <= r) {
            help[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
        }

        // 下面的两个while 只可能加入一个
        while (p1 <= mid) {
            help[i++] = arr[p1++];
        }

        while (p2 <= r) {
            help[i++] = arr[p2++];
        }

        // 将排序好的部分[l..r]放回去
        for (i = 0; i < help.length; i++) {
            arr[l + i] = help[i];
        }

        // 理解完全错误
        // help 只是arr 原数组的一部分数据
        // arr = help;
    }
}
